#!/usr/bin/env python

class Dictionary():
	def __init__(self):
		self._load_bnc_list()
		pass

	# return index of w in words
	# w : word string
	# words : list of objects whose first entry is word string
	def _search(self, w, words):
		start = 0
		end = len(words)

		while (start < end):
			mid = start + (end-start) / 2
			if w == words[mid][0]:
				return mid
			elif (w < words[mid][0]):
				end = mid
			else:
				start = mid+1
		
		raise ValueError(w + " is not in list")

	def get_family(self, w):
		try:
			index = self._search(w, self.wlist)
			return self.wlistf[self.wlist[index][1]][0]
		except ValueError:
			return None

	def get_members(self, wf):
		try:
			i = self._search(wf, self.wlistf)
			words = map(lambda y: y[0], filter(lambda x: x[1] == i, self.wlist))
			return words
		except ValueError:
			return []

	def has(self, w):
		try :
			i = self._search(w, self.wlist)
			return True
		except:
			return False

	def _load_bnc_list(self):
		path="bnc/"
		lists=[]

		for i in range(1,15):
			fn = path+("basewrd%d.txt" % i)
			f = open(fn, "rt")

			for line in f:
				line = line.replace("\r", "").replace("\n", "")
				if len(line) == 0:
					continue
				if line[0] != '\t':
					lists.append([i, line.split()[0]])
				else:
					lists[-1].append(line.split()[0])

		for i in range(15, 21):
			fn = path+("basewrd%d.txt" % i)
			f = open(fn, "rt")

			for line in f:
				line = line.replace("\r", "").replace("\n", "")
				line = line.replace("> ", "")
				if len(line) == 0:
					continue
				lists.append([i] + line.split())
		
		# make words lowercase
		# lists consists word families of "<level> <family word> <other member words>*"
		lists = map(lambda x: [x[0]] + map(lambda y: y.lower(), x[1:]), lists)
		lists = sorted(lists, key=lambda x: x[1])

		# wlistf is a sorted list of [family word, level]
		# wlist is a sorted list of [word, family word index]
		self.wlistf = []
		self.wlist = []

		for i in range(len(lists)):
			w = lists[i]
			self.wlistf.append([w[1], w[0]])
			self.wlist += zip(w[1:], [i for k in range(len(w)-1)])
	
		self.wlist = sorted(self.wlist, key=lambda x: x[0])

if __name__=="__main__":
	d = Dictionary()
	print d._search("help", d.wlist)
	print d.get_family("help")
	print d.get_family("helped")
	print d.get_members("help")
